{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "# importing libs\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from keras.layers import Input, Dense, GaussianNoise\n",
    "from keras.models import Model\n",
    "from keras import regularizers\n",
    "from keras.layers.normalization import BatchNormalization\n",
    "from keras.optimizers import SGD\n",
    "import random as rn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "M: 16 k: 4\n"
     ]
    }
   ],
   "source": [
    "# defining parameters\n",
    "M = 16 \n",
    "k = np.log2(M)\n",
    "k = int(k)\n",
    "print ('M:',M,'k:',k)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#generating data of size N\n",
    "N = 10000\n",
    "label = np.random.randint(M,size=N)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# creating one hot encoded vectors\n",
    "data = []\n",
    "for i in label:\n",
    "    temp = np.zeros(M)\n",
    "    temp[i] = 1\n",
    "    data.append(temp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10000, 16)\n"
     ]
    }
   ],
   "source": [
    "data = np.array(data)\n",
    "print (data.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.  0.  0.  0.]\n",
      "6 [ 0.  0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      "4 [ 0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      "5 [ 0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      "2 [ 0.  0.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      "12 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.  0.  0.]\n",
      "13 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.  0.]\n",
      "14 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.]\n",
      "14 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.]\n"
     ]
    }
   ],
   "source": [
    "temp_check = [17,23,45,67,89,96,72,250,350]\n",
    "for i in temp_check:\n",
    "    print(label[i],data[i])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7\n"
     ]
    }
   ],
   "source": [
    "R = 4/7\n",
    "n_channel = 7\n",
    "print (int(k/R))\n",
    "input_signal = Input(shape=(M,))\n",
    "encoded = Dense(M, activation='relu')(input_signal)\n",
    "encoded1 = Dense(n_channel, activation='linear')(encoded)\n",
    "encoded2 = BatchNormalization()(encoded1)\n",
    "\n",
    "EbNo_train = 5.01187 #  coverted 7 db of EbNo\n",
    "encoded3 = GaussianNoise(np.sqrt(1/(2*R*EbNo_train)))(encoded2)\n",
    "\n",
    "decoded = Dense(M, activation='relu')(encoded3)\n",
    "decoded1 = Dense(M, activation='softmax')(decoded)\n",
    "\n",
    "autoencoder = Model(input_signal, decoded1)\n",
    "#sgd = SGD(lr=0.001)\n",
    "autoencoder.compile(optimizer='adam', loss='categorical_crossentropy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_5 (InputLayer)         (None, 16)                0         \n",
      "_________________________________________________________________\n",
      "dense_9 (Dense)              (None, 16)                272       \n",
      "_________________________________________________________________\n",
      "dense_10 (Dense)             (None, 7)                 119       \n",
      "_________________________________________________________________\n",
      "batch_normalization_3 (Batch (None, 7)                 28        \n",
      "_________________________________________________________________\n",
      "gaussian_noise_3 (GaussianNo (None, 7)                 0         \n",
      "_________________________________________________________________\n",
      "dense_11 (Dense)             (None, 16)                128       \n",
      "_________________________________________________________________\n",
      "dense_12 (Dense)             (None, 16)                272       \n",
      "=================================================================\n",
      "Total params: 819\n",
      "Trainable params: 805\n",
      "Non-trainable params: 14\n",
      "_________________________________________________________________\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "print (autoencoder.summary())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "N_val = 1500\n",
    "val_label = np.random.randint(M,size=N_val)\n",
    "val_data = []\n",
    "for i in val_label:\n",
    "    temp = np.zeros(M)\n",
    "    temp[i] = 1\n",
    "    val_data.append(temp)\n",
    "val_data = np.array(val_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 10000 samples, validate on 1500 samples\n",
      "Epoch 1/17\n",
      "10000/10000 [==============================] - 0s - loss: 2.4397 - val_loss: 2.6391\n",
      "Epoch 2/17\n",
      "10000/10000 [==============================] - 0s - loss: 1.9941 - val_loss: 2.4919\n",
      "Epoch 3/17\n",
      "10000/10000 [==============================] - 0s - loss: 1.6196 - val_loss: 2.2910\n",
      "Epoch 4/17\n",
      "10000/10000 [==============================] - 0s - loss: 1.2889 - val_loss: 2.0355\n",
      "Epoch 5/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.9983 - val_loss: 1.7330\n",
      "Epoch 6/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.7578 - val_loss: 1.4023\n",
      "Epoch 7/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.5730 - val_loss: 1.0829\n",
      "Epoch 8/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.4313 - val_loss: 0.7943\n",
      "Epoch 9/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.3188 - val_loss: 0.5534\n",
      "Epoch 10/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.2373 - val_loss: 0.3709\n",
      "Epoch 11/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.1768 - val_loss: 0.2380\n",
      "Epoch 12/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.1325 - val_loss: 0.1516\n",
      "Epoch 13/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.1031 - val_loss: 0.0992\n",
      "Epoch 14/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.0803 - val_loss: 0.0669\n",
      "Epoch 15/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.0637 - val_loss: 0.0467\n",
      "Epoch 16/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.0544 - val_loss: 0.0343\n",
      "Epoch 17/17\n",
      "10000/10000 [==============================] - 0s - loss: 0.0440 - val_loss: 0.0258\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7f37be5e56a0>"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "autoencoder.fit(data, data,\n",
    "                epochs=17,\n",
    "                batch_size=300,\n",
    "                validation_data=(val_data, val_data))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from keras.models import load_model\n",
    "#autoencoder.save('4_7_symbol_autoencoder_v_best.model')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#autoencoder_loaded = load_model('4_7_symbol_autoencoder_v_best.model')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "encoder = Model(input_signal, encoded2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "encoded_input = Input(shape=(n_channel,))\n",
    "\n",
    "deco = autoencoder.layers[-2](encoded_input)\n",
    "deco = autoencoder.layers[-1](deco)\n",
    "# create the decoder model\n",
    "decoder = Model(encoded_input, deco)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "N = 45000\n",
    "test_label = np.random.randint(M,size=N)\n",
    "test_data = []\n",
    "\n",
    "for i in test_label:\n",
    "    temp = np.zeros(M)\n",
    "    temp[i] = 1\n",
    "    test_data.append(temp)\n",
    "    \n",
    "test_data = np.array(test_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0 13\n"
     ]
    }
   ],
   "source": [
    "temp_test = 6\n",
    "print (test_data[temp_test][test_label[temp_test]],test_label[temp_test])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<keras.engine.training.Model at 0x7f37beeaccc0>"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "autoencoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def frange(x, y, jump):\n",
    "  while x < y:\n",
    "    yield x\n",
    "    x += jump"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SNR: -4 BER: 0.341422222222\n",
      "SNR: -3.5 BER: 0.306422222222\n",
      "SNR: -3.0 BER: 0.266755555556\n",
      "SNR: -2.5 BER: 0.233888888889\n",
      "SNR: -2.0 BER: 0.195488888889\n",
      "SNR: -1.5 BER: 0.168711111111\n",
      "SNR: -1.0 BER: 0.132488888889\n",
      "SNR: -0.5 BER: 0.109\n",
      "SNR: 0.0 BER: 0.0812444444444\n",
      "SNR: 0.5 BER: 0.0620222222222\n",
      "SNR: 1.0 BER: 0.0431555555556\n",
      "SNR: 1.5 BER: 0.0314444444444\n",
      "SNR: 2.0 BER: 0.0214222222222\n",
      "SNR: 2.5 BER: 0.0152888888889\n",
      "SNR: 3.0 BER: 0.00926666666667\n",
      "SNR: 3.5 BER: 0.00515555555556\n",
      "SNR: 4.0 BER: 0.00328888888889\n",
      "SNR: 4.5 BER: 0.00164444444444\n",
      "SNR: 5.0 BER: 0.000644444444444\n",
      "SNR: 5.5 BER: 0.000355555555556\n",
      "SNR: 6.0 BER: 0.000133333333333\n",
      "SNR: 6.5 BER: 0.000155555555556\n",
      "SNR: 7.0 BER: 4.44444444444e-05\n",
      "SNR: 7.5 BER: 2.22222222222e-05\n",
      "SNR: 8.0 BER: 0.0\n"
     ]
    }
   ],
   "source": [
    "EbNodB_range = list(frange(-4,8.5,0.5))\n",
    "ber = [None]*len(EbNodB_range)\n",
    "for n in range(0,len(EbNodB_range)):\n",
    "    EbNo=10.0**(EbNodB_range[n]/10.0)\n",
    "    noise_std = np.sqrt(1/(2*R*EbNo))\n",
    "    noise_mean = 0\n",
    "    no_errors = 0\n",
    "    nn = N\n",
    "    noise = noise_std * np.random.randn(nn,n_channel)\n",
    "    encoded_signal = encoder.predict(test_data) \n",
    "    final_signal = encoded_signal + noise\n",
    "    pred_final_signal =  decoder.predict(final_signal)\n",
    "    pred_output = np.argmax(pred_final_signal,axis=1)\n",
    "    no_errors = (pred_output != test_label)\n",
    "    no_errors =  no_errors.astype(int).sum()\n",
    "    ber[n] = no_errors / nn \n",
    "    print ('SNR:',EbNodB_range[n],'BER:',ber[n])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f37be21cb70>"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.plot(EbNodB_range, ber, 'bo',label='Autoencoder(7,4)')\n",
    "#plt.plot(list(EbNodB_range), ber_theory, 'ro-',label='BPSK BER')\n",
    "plt.yscale('log')\n",
    "plt.xlabel('SNR Range')\n",
    "plt.ylabel('Block Error Rate')\n",
    "plt.grid()\n",
    "plt.legend(loc='upper right',ncol = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY4AAAEKCAYAAAAFJbKyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XuYVPWd5/H3V9QAQhyjyOME6WYGr2kuSosSYqA1uCQq\nbNQY2A47iSRsfCCayyaa4Iy6idEncUxiIOPijWRlu+P9QZeJjnJRiSigRBQvIUobwAREBVoGI/Z3\n/zhVbXfTVX1OVZ+qU6c+r+epp+v86lx+v4bub//u5u6IiIiEdUC5MyAiIpVFgUNERCJR4BARkUgU\nOEREJBIFDhERiUSBQ0REIlHgEBGRSBQ4REQkEgUOERGJ5MByZyAORxxxhNfW1hZ07bvvvsshhxzS\nuxkqE5UledJSDlBZkqjYcqxdu/ZNdx/U03mpDBy1tbWsWbOmoGuXL1/OxIkTezdDZaKyJE9aygEq\nSxIVWw4zawlzXqqaqszsXDNbsHPnznJnRUQktVIVONz9AXefdeihh5Y7KyIiqZWqwCEiIvFLZR+H\niET3/vvvs3nzZvbu3Rvq/EMPPZQXX3wx5lyVRlrKErYcffv2ZciQIRx00EEFPUeBQ0QA2Lx5MwMH\nDqS2thYz6/H83bt3M3DgwBLkLH5pKUuYcrg7O3bsYPPmzQwbNqyg56SqqaqYzvFFi6C2Fs44YwK1\ntcGxSDXZu3cvhx9+eKigIZXLzDj88MND1yy7k6rAUWjn+KJFMGsWtLSAu9HSEhwreEi1UdCoDsX+\nO6cqcBRq7lzYs6dz2p49QXo+2VrKAQegWoqIVA0FDuD116OlQ9daCqqliPSS+++/HzPjpZde6vHc\nn//85+zp+ldfmS1cuJA5c+ZEvu7ZZ59l5syZAPz0pz9l9OjRjB49mrq6Ovr06cNbb72V89opU6ZQ\nV1fXfjxv3jxuu+226JkPSYEDGDo0WjoUXksRSYs77zwwlhp3U1MTn/rUp2hqaurx3CQGjqj27dsH\nwI9//GMuueQSAL773e+ybt061q1bx7XXXsuECRP42Mc+1u319957LwMGDOiUdtFFF/HLX/4ytjwr\ncADXXAP9+3dO698/SM+l0FqKmrYkDRYtgm98o2+v17hbW1t54oknuPXWW2lubgaCZTTOOeec9nPm\nzJnDwoULufHGG9m6dSsNDQ00NDQAQdAZMWIEdXV1XHbZZe3XPPzww4wbN46TTz6ZL3zhC7S2tgLB\n8kRXXnklp59+OiNGjGiv5bS2tvKVr3yFESNGMHLkSO65556897/99ts59thjGTt2LCtXrmxP3759\nO+effz6nnHIKp5xySvtnV111FTNmzGD8+PHMmDGD3bt389xzzzFq1Kj9vidNTU1Mnz495/frhhtu\n4IorruiU3r9/f2pra3n66adDfucjcvfUvIBzgQXDhw/3qO64w72mxt2szWtqguN8amrcgx+Zzq+a\nmtz379+/87n9+/f8nGIsW7YsvpuXWFrKkuRybNiwIfS5Uf//h3XHHXf4RRdd5O7u48aN8zVr1viy\nZcv87LPPbj9n9uzZfvvtt2fyUePbt293d/ctW7b40Ucf7du2bfP333/fGxoa/L777vPt27f76aef\n7q2tre7uft111/nVV1/dfv2NN97ou3bt8vnz5/vMmTPd3f173/ueX3rppe3PfOutt3Lef+vWre3p\n7733nn/yk5/02bNnu7v79OnT/fHHH3d395aWFj/++OPd3f3KK6/0k08+2ffs2ePu7kuXLvXzzjtv\nv+/Hu+++64cddpjv2LGj2+/XN7/5Tb/33nv9tdde80984hO+a9eu9s9+9KMf+fXXX5/ze93dvzew\nxkP8rk1VjcOLWHKksRE2bYKlS1ewaVNwnE/UWoqatiRNCqlxh9HU1MS0adMAmDZtWqjmqqzVq1cz\nceJEBg0axIEHHkhjYyOPPfYYq1atYsOGDYwfP57Ro0fz61//mpaWD9fyO++88wAYM2YMmzZtAuCR\nRx5h9uzZ7eccdthhOe//1FNPtacffPDBfPGLX2y/7pFHHmHOnDmMHj2aKVOmsGvXrvbazpQpU+jX\nrx8Ab7zxBoMG7b8o7QMPPMD48eO7baZat24df/rTn/j85z/f7ffjyCOPZOvWraG/f1FoAmCBsoFl\n7tzgh2Xo0CBo5Ao4hf6gLVoU/hkipTJ0aNA81V16od566y2WLl3K+vXrMTM++OADzIypU6fS1tbW\nfl7U+QfuzqRJk3IGoY985CMA9OnTp72/obe0tbWxatUq+vbtu99nHZc/79evX7flam5uztlM9eST\nT7JmzRpqa2vZt28f27Zt43Of+xyPP/44EHyfsoGpt6WqxlFq2VpKWxs91lIK6YDXyC1JqmuugX79\nvFNaT/2CPbn77ruZMWMGLS0tbNq0iT//+c8MGzaMtrY2NmzYwHvvvcc777zDo48+2n7NwIED2b17\n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\nJP8fv+AmRWtmIiQAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f37be21c208>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.savefig('AutoEncoder_7_4_BER_matplotlib')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
